#pragma once
#include "CryptoRecipient.h"
#include "CryptoMetadata.h"

#include <fstream>
#include <vector>

namespace kryptos { namespace cryptography {

class CryptoMetadata;

class CryptoFile
{
public:

    enum CryptoFormat { K_UNKNOWN, K_PK01, K_OTPRSA01 };

    CryptoFile(const std::string& filename);
    CryptoFile(const std::string& filename, CryptoFormat format);

    virtual ~CryptoFile();

    void addRecipient(const CryptoRecipient& recipient);
    void setMetadata (const CryptoMetadata& metadata);

    std::ostream& outputStream();
    std::istream& inputStream ();

    unsigned long long size      ();
    unsigned long long cryptoSize();

    unsigned long long cryptoDataOffset();
    unsigned long long cryptoDataEnd   ();

    CryptoFormat format();

    std::vector<CryptoRecipient> recipients();
    CryptoMetadata               metadata();

private:

    void init(const std::string& filename);
    void load();

    CryptoMetadata               m_cryptoMetadata;
    CryptoFormat                 m_format;
    std::fstream                 m_stream;
    unsigned long long           m_generalHeader;
    unsigned long long           m_recipientsOffset;
    unsigned long long           m_currentOffset;
    unsigned long long           m_cipherOffset;
    unsigned long long           m_metadataOffset;
    int                          m_recipientsCount;
    long long                    m_recipientsSize;
    bool                         m_openForWritting;
    std::vector<CryptoRecipient> m_recipients;
    std::vector<unsigned char>   m_metadataBytes;

};

}}
